package gui;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import containers.NewLoanContainer;
import containers.StudentContainer;
import dbadapters.AddStudentDB;
import dbadapters.checkConnection;

import entities.CoSigner;
import entities.FinancialInfo;
import entities.Loan;
import entities.Student;

/**
 * Panel for main student loan application
 * 
 * @author gke703
 */
public class ApplicationPanel extends JPanel {

	/** panel for personal info */
	protected PersonalInfoPanel lpanel;

	/** panel for student info, institution etc. */
	protected StudentInfoPanel rpanel;

	/** panel for financial info */
	protected FinancialInfoPanel lpanel2;

	/** panel for loan information */
	protected LoanInfoPanel rpanel2;

	/** frame that panel is being displayed in */
	private JFrame myFrame;

	/**
	 * displays panels in a 2 by 2 grid layout
	 * 
	 * @param frame
	 *            frame panel is being displayed in
	 */
	public ApplicationPanel(JFrame frame) {

		myFrame = frame;
		// setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		setLayout(new GridLayout(2, 2));

		lpanel = new PersonalInfoPanel();
		add(lpanel);

		rpanel = new StudentInfoPanel();
		add(rpanel);

		lpanel2 = new FinancialInfoPanel();
		add(lpanel2);

		rpanel2 = new LoanInfoPanel();
		JButton bu = rpanel2.confirmButton;
		ApplyListener listener = new ApplyListener();
		bu.addActionListener(listener);
		add(rpanel2);

	}

	/**
	 * sorts out input from panels and creates a student when apply is pressed
	 * error checks extensively
	 * 
	 * @author gke703
	 */
	private class ApplyListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent event) {
			// sort out filled out info to create a new student and place
			// him/her in container

			boolean isValid = true; // manage if input to application form is
			// valid or not
			String errorString = ""; // error message if needed

			String studentName = lpanel.nameField.getValueAsString();
			// check if input is alphanumeric
			String remainingJunk = studentName.replaceAll("[a-zA-Z ]", "");
			if (remainingJunk.length() > 0 || studentName.length() == 0) {
				errorString += "Invalid input for Name\n";
				isValid = false;
			}

			// get birthdate info in format MM/dd/yyyy
			String studentBirthdate = lpanel.birthdateField.getValueAsString();
			remainingJunk = studentBirthdate.replaceAll("[0-9/]", "");
			// check for proper format
			boolean isValidDate = studentBirthdate
					.matches("[0-1][0-9]/[0-3][0-9]/[0-2][90][0-9][0-9]");
			if (!isValidDate || remainingJunk.length() > 0) {
				errorString += "Invalid input for birthdate, should be mm/dd/yyyy\n";
				isValid = false;
			}

			String studentAddress = lpanel.addressField.getValueAsString();
			remainingJunk = studentAddress.replaceAll("[a-zA-Z.0-9 ]", "");
			if (remainingJunk.length() > 0 || studentAddress.length() == 0) {
				errorString += "Invalid input for Address\n";
				isValid = false;
			}

			String studentPhone = lpanel.phonenumberField.getValueAsString();
			remainingJunk = studentPhone.replaceAll("[0-9 ()-]", "");
			if (remainingJunk.length() > 0 || studentPhone.length() == 0) {
				errorString += "Invalid input for Phone Number\n";
				isValid = false;
			}

			String studentEmail = lpanel.emailField.getValueAsString();
			remainingJunk = studentEmail.replaceAll("[a-zA-Z0-9.@()-]", "");
			if (remainingJunk.length() > 0 || studentEmail.length() == 0) {
				errorString += "Invalid input for e-mail\n";
				isValid = false;
			}

			String studentCollege = rpanel.collegeField.getValueAsString();
			// check if input is alphabetic
			remainingJunk = studentCollege.replaceAll("[a-zA-Z ]", "");
			if (remainingJunk.length() > 0 || studentCollege.length() == 0) {
				errorString += "Invalid input for College enrolled at\n";
				isValid = false;
			}

			boolean studentCitizen = rpanel.citizenCheck.isSelected();

			// now get proper enumerated value for marital status
			String studentMaritalName = rpanel.maritalBox.getSelection();
			studentMaritalName = studentMaritalName.toUpperCase();
			Student.maritalStatuses studentMarital = Student.maritalStatuses.SINGLE;
			if (studentMaritalName.contentEquals("SINGLE")) {
				studentMarital = Student.maritalStatuses.SINGLE;
			} else if (studentMaritalName.contentEquals("MARRIED")) {
				studentMarital = Student.maritalStatuses.MARRIED;
			} else if (studentMaritalName.contentEquals("COMMONLAW")) {
				studentMarital = Student.maritalStatuses.COMMONLAW;
			}

			// do a similar process for mother/father education levels
			String studentFatherString = rpanel.fatherBox.getSelection();
			studentFatherString = studentFatherString.toUpperCase();
			Student.education studentFather = Student.education.NONE;
			if (studentFatherString.contentEquals("DEGREE")) {
				studentFather = Student.education.DEGREE;
			} else if (studentFatherString.contentEquals("DIPLOMA")) {
				studentFather = Student.education.DIPLOMA;
			} else if (studentFatherString.contentEquals("HIGH SCHOOL")) {
				studentFather = Student.education.HIGH_SCHOOL;
			}

			// do a similar process for mother/father education levels
			String studentMotherString = rpanel.motherBox.getSelection();
			studentMotherString = studentMotherString.toUpperCase();
			Student.education studentMother = Student.education.NONE;
			if (studentMotherString.contentEquals("DEGREE")) {
				studentMother = Student.education.DEGREE;
			} else if (studentMotherString.contentEquals("DIPLOMA")) {
				studentMother = Student.education.DIPLOMA;
			} else if (studentMotherString.contentEquals("HIGH SCHOOL")) {
				studentMother = Student.education.HIGH_SCHOOL;
			}

			String studentSIN = rpanel.sinField.getValueAsString();
			// check if input is numeric
			remainingJunk = studentSIN.replaceAll("[0-9]", "");
			if (studentSIN.length() != 9) {
				errorString += "student SIN must be 9 digits long\n";
				isValid = false;
			} else if (remainingJunk.length() > 0 || studentSIN.length() == 0) {
				errorString += "Invalid input for student SIN\n";
				isValid = false;
			}

			float studentPersonalIncome = 0;
			try {
				studentPersonalIncome = lpanel2.personalField.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentPersonalIncome = 0;
			}

			if (studentPersonalIncome < 0) {
				isValid = false;
				errorString += "Personal Income must be positive\n";
			}

			float studentHouseholdIncome = 0;
			try {
				studentHouseholdIncome = lpanel2.householdField
						.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentHouseholdIncome = 0;
			}

			if (studentHouseholdIncome < 0) {
				isValid = false;
				errorString += "Household Income must be positive\n";
			}

			float studentTaxIncome = 0;
			try {
				studentTaxIncome = lpanel2.taxField.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentTaxIncome = 0;
			}

			if (studentTaxIncome < 0) {
				isValid = false;
				errorString += "Taxable Income must be positive\n";
			}

			float studentChildSupport = 0;
			try {
				studentChildSupport = lpanel2.childField.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentChildSupport = 0;
			}

			if (studentChildSupport < 0) {
				isValid = false;
				errorString += "Child Support must be positive\n";
			}

			float studentScholarship = 0;
			try {
				studentScholarship = lpanel2.scholarField.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentScholarship = 0;
			}

			if (studentScholarship < 0) {
				isValid = false;
				errorString += "Scholarship must be positive\n";
			}

			float studentMonthlyExpenses = 0;
			try {
				studentMonthlyExpenses = lpanel2.monthlyExpensesField
						.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentMonthlyExpenses = 0;
			}

			if (studentMonthlyExpenses < 0) {
				isValid = false;
				errorString += "Monthly Expenses must be positive\n";
			}

			double studentRequestedAmount = 0;
			try {
				studentRequestedAmount = rpanel2.amountField.getValueAsFloat();
			} catch (NumberFormatException e) {
				isValid = false;
				errorString += e.getMessage() + "\n";
				studentRequestedAmount = 0;
			}

			if (studentRequestedAmount < 0) {
				isValid = false;
				errorString += "Requested Amount must be positive\n";
			}

			String studentPassword = "";
			studentPassword = rpanel2.passwordField.getValueAsString();
			if (studentPassword.length() == 0) {
				isValid = false;
				errorString += "You must enter a password\n";
			}

			CoSigner myCosigner = rpanel2.appCosigner;
			if (myCosigner == null) {
				isValid = false;
				errorString += "You must fill out a cosigner\n";
			}

			if (!isValid) {
				JOptionPane.showMessageDialog(myFrame, errorString);
			} else {
				// student and loan are ready to be built and placed into the
				// system

				Set<Integer> ids = StudentContainer.dictionary().keySet();
				Object[] idsArray = ids.toArray();

				int newID = 123455;

				for (int i = 0; i < idsArray.length; i++) {
					if (newID < (Integer) idsArray[i]) {
						newID = (Integer) idsArray[i];
					}
				}
				newID = newID + 1;

				Student myStudent = new Student(newID, studentPassword);
				myStudent.setAddress(studentAddress);
				myStudent.setBirthdate(studentBirthdate);
				myStudent.setCitizenship(studentCitizen);
				myStudent.setEmail(studentEmail);
				myStudent.setFatherEducation(studentFather);
				myStudent.setInstitution(studentCollege);
				myStudent.setMaritalStatus(studentMarital);
				myStudent.setMotherEducation(studentMother);
				myStudent.setName(studentName);
				myStudent.setPhoneNumber(studentPhone);
				myStudent.setSIN(studentSIN);

				FinancialInfo myFinances = new FinancialInfo();
				myFinances.setChildSupport(studentChildSupport);
				myFinances.setHouseholdIncome(studentHouseholdIncome);
				myFinances.setPersonalIncome(studentPersonalIncome);
				myFinances.setScholarship(studentScholarship);
				myFinances.setTaxableEarnings(studentTaxIncome);
				myFinances.setMonthlyExpenses(studentMonthlyExpenses);

				myStudent.setFinances(myFinances);

				Loan newLoan = new Loan(myStudent);
				newLoan.setAmountRequested(studentRequestedAmount);
				myStudent.setLoan(newLoan);

				newLoan.setCosigner(myCosigner);
				myCosigner.setCosignedLoan(newLoan);

				StudentContainer.dictionary().put(myStudent.getID(), myStudent);
				NewLoanContainer.dictionary().put(myStudent.getID(), myStudent);

				// add student to db if possible
				checkConnection c = new checkConnection();

				if (c.isConnectionValid()) {
					new AddStudentDB(myStudent);
				} else {
					System.out.println(c.getErrorMessage());
				}

				JOptionPane.showMessageDialog(myFrame, "Success!");
				myFrame.setVisible(false);

				System.out.println(myStudent.getLoan().getCosigner());
			}

		}
	}

	private static final long serialVersionUID = 1L;

}